package vcp.client.GUI.mvc.controller;

import java.util.ArrayList;

import javax.swing.JComponent;

import org.joda.time.DateTime;

import vcp.client.GUI.mvc.model.UIAbstractModel;
import vcp.client.GUI.mvc.view.UIAbstractView;
import vcp.client.interfaces.delegates.IControllerModelDelegate;
import vcp.client.interfaces.delegates.IControllerViewDelegate;
import vcp.client.interfaces.delegates.IParentControllerDelegate;
import vcp.enums.PopUpMessageType;
import vcp.enums.Screen;

/**
 * 
 * @author VCP team
 *         <p>
 *         Main abstract controller
 *         </p>
 * @see IControllerViewDelegate
 * @see IControllerModelDelegate
 */
public abstract class UIAbstractController implements IControllerViewDelegate, IControllerModelDelegate
{
	// ****************************************************************************************************************************
	// Setter-Getter methods
	// ****************************************************************************************************************************
	/** screen type name **/
	private final Screen screenName;

	public Screen getScreenName ()
	{
		return this.screenName;
	}

	/** save the parent delegate **/
	protected IParentControllerDelegate parentDelegate;

	public void setParentControllerDelegate ( IParentControllerDelegate parentDelegate )
	{
		this.parentDelegate = parentDelegate;
	}

	protected UIAbstractController ( Screen screenName )
	{
		this.screenName = screenName;
	}

	// ****************************************************************************************************************************
	// Public methods
	// ****************************************************************************************************************************
	/**
	 * @return Controller's view
	 */
	public abstract UIAbstractView getView ();

	/**
	 * 
	 * @return Controller's model
	 */
	public abstract UIAbstractModel getModel ();

	/**
	 * 
	 * @return ArrayList with additional components to place on toolBar
	 */
	public ArrayList <JComponent> getAdditionalToolbarComponents ()
	{
		return this.getView().getAdditionalToolbarComponents();
	}

	/**
	 * clears the model and view
	 */
	public void clearMVC ()
	{
		this.getView().clearView();
		this.getView().resetView();
	}

	/**
	 * Clear all the data when user log out
	 */
	public void flashData ()
	{

	}

	/**
	 * hook method, will be overridden by derived classes will be used for outer
	 * system to inject new MVC with data
	 * 
	 * @param data
	 */
	public void uploadDataContext ( Object data )
	{
	}

	// ****************************************************************************************************************************
	// Protected methods
	// ****************************************************************************************************************************
	/**
	 * register all relevant listeners to perform callback
	 */
	protected void setupListeners ()
	{
		this.getView().setControllerDelegate(this);
		this.getModel().setControllerDelegate(this);
	}

	/**
	 * hook method, will be overridden by derived classes will be used by MVC to
	 * retrieve data from model and place into view
	 */
	protected void reloadGUI ()
	{

	}

	// ****************************************************************************************************************************
	// IControllerViewDelegate methods
	// ****************************************************************************************************************************
	@Override
	public void onButtonPress ( Object object )
	{
		Screen newScreen = (Screen) object;
		this.parentDelegate.loadMVC(newScreen);
	}

	// ****************************************************************************************************************************
	// IMessage methods
	// ****************************************************************************************************************************
	@Override
	public void showPopUpMessage ( String displayMessage, PopUpMessageType messageType )
	{
		this.parentDelegate.showPopUpMessage(displayMessage, messageType);
	}

	@Override
	public DateTime requestCurrentClientDateTime ()
	{
		return this.parentDelegate.requestCurrentClientDateTime();
	}

	// ****************************************************************************************************************************
	// INotify methods
	// ****************************************************************************************************************************
	@Override
	public void onTimeChange ( DateTime currentTime )
	{

	}

	@Override
	public void loadMVC ( Screen name )
	{
		this.parentDelegate.loadMVC(name);
	}

	@Override
	public void loadMVCWithData ( Screen name, Object data )
	{
		this.parentDelegate.loadMVCWithData(name, data);
	}

	@Override
	public void loadingStart ()
	{
		this.parentDelegate.loadingStart();
	}

	@Override
	public void loadingStop ()
	{
		this.parentDelegate.loadingStop();
	}

	// ****************************************************************************************************************************
	// IControllerModelDelegate methods
	// ****************************************************************************************************************************
	/**
	 * hook method, will be overridden by derived classes will be used by model
	 * to notify controller that it hold new data
	 */
	@Override
	public void updateControllerDelegateWithData ( Object newData )
	{
	}
}
